﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Xml.Linq;
using System.Xml;
using System.Xml.Serialization;
using JCore.LoLChat;
using JCore.LoLProfiler_Test.Classes.API;
using JCore.LoLProfiler_Test.Classes.Objects;
using LoL_Profiler;
using Friend = JCore.LoLProfiler_Test.Classes.Objects.Friend;

namespace JCore.LoLProfiler_Test.Classes
{
    public class DatabaseGeneration
    {
        public Summoner newDatabase = new Summoner();
        public Summoner UpdateDatabase(string summonerName, Summoner oldDatabase, bool updateSummonerInfo = false)
        {
            newDatabase.LoginInfo = oldDatabase.LoginInfo;
            newDatabase.LoginInfo.Password = PasswordEncrypt.Encrypt(newDatabase.LoginInfo.Password);
            newDatabase.SummonerInfo = !updateSummonerInfo ? oldDatabase.SummonerInfo : CreateSummonerInfoObject(summonerName);
            newDatabase.Matches = oldDatabase.Matches;
            Match latestMatch = GetLatestMatch(summonerName, newDatabase.SummonerInfo.AccountId,
                                               newDatabase.SummonerInfo.Friends);
            if (latestMatch.Players.Count > 0)
            {
                newDatabase.Matches.Add(latestMatch);
            }
            return newDatabase;
        }


        /// <summary>
        /// Create Summoner Object with everything in it
        /// </summary>
        /// <param name="username"></param>
        /// <param name="password"></param>
        /// <param name="summonerName"></param>
        /// <param name="friends"></param>
        /// <returns></returns>
        public Summoner CreateSummonerObject(string username, string password, string summonerName, List<Friend> friends)
        {
            // new summoner object
            Summoner data = new Summoner();

            // Add Login Info
            LoginInfo login = new LoginInfo();
            login.LoginName = username;
            login.Password = PasswordEncrypt.Encrypt(password);
            data.LoginInfo = login;

            // Add Summoner Info
            data.SummonerInfo = CreateSummonerInfoObject(summonerName);
            data.SummonerInfo.Friends = friends;

            Console.WriteLine("Starting to generate matches...");
            // Add Matches
            data.Matches = CreateMatchesList(data.SummonerInfo.Name,
                                             data.SummonerInfo.AccountId.ToString(CultureInfo.InvariantCulture),
                                             data.SummonerInfo.Friends);

            return data;
        }

        /// <summary>
        /// Get Info of summoner
        /// </summary>
        /// <param name="summonerName"></param>
        /// <returns></returns>
        public SummonerInfo CreateSummonerInfoObject(string summonerName)
        {
            SummonerInfo data = new SummonerInfo();
            ElophantAPI.Summoner.Data summoner = JSONdownloader.SummonerProfile(summonerName);
            data.AccountId = summoner.acctId.ToString();
            data.Name = summoner.name;
            data.RevisionDate = summoner.revisionDate;
            data.SummonerId = summoner.summonerId.ToString();
            return data;
        }

        /// <summary>
        ///  Create list of matches and add the matches who are relevant (premade friends) to the list
        /// </summary>
        /// <param name="summonerName"></param>
        /// <param name="friends"></param>
        /// <returns></returns>
        private List<Match> CreateMatchesList(string summonerName, string accountID, List<Friend> friends)
        {
            // Load Objects
            ObjectConvertors convertors = new ObjectConvertors();
            List<Match> matchesList = new List<Match>();

            // Get data from response and put it in an object (Recent Matches)
            ElophantAPI.RecentGames.Data matches = JSONdownloader.RecentGames(accountID);
            // Start at the end of the matchlist, most relevant...
            for (int i = 9; i > -1; i--)
            {
                // Get players from that game
                List<ElophantAPI.RecentGames.FellowPlayer> matchFriendList =
                    new List<ElophantAPI.RecentGames.FellowPlayer>();
                // Check if premade
                if (matches.gameStatistics[i].premadeSize > 0)
                {
                    // If so,
                    // For each person in the game, check if in your team, yes? check if it is a friend and if so, add to list.
                    for (int j = 0; j < matches.gameStatistics[i].fellowPlayers.Count; j++)
                    {
                        if (matches.gameStatistics[i].fellowPlayers[j].teamId == matches.gameStatistics[i].teamId)
                        {
                            Friend derp =
                                friends.FirstOrDefault(
                                    f => f.Name == matches.gameStatistics[i].fellowPlayers[j].summonerName);
                            if (derp != null)
                            {
                                matchFriendList.Add(matches.gameStatistics[i].fellowPlayers[j]);
                            }
                        }
                    }

                    // Done checking friends for 1 game, convert the statistics to match object to add to database
                    Match generatedMatch = convertors.GameStatisticsToMatchObject(summonerName,
                                                                                  matches.gameStatistics[i
                                                                                      ], matchFriendList);
                    if (generatedMatch.Players.Count != 0)
                    {
                        Player me = new Player
                            {
                                Name = summonerName,
                                Champion = matches.gameStatistics[i].championId,
                                Kills = convertors.Kills(matches.gameStatistics[i].statistics),
                                Deaths = convertors.Deaths(matches.gameStatistics[i].statistics),
                                Assists = convertors.Assists(matches.gameStatistics[i].statistics)
                            };
                        me.Score = (me.Kills + (me.Assists / 2) - me.Deaths);
                        generatedMatch.Players.Add(me);
                        matchesList.Add(generatedMatch);
                    }
                }
            }

            return matchesList;
        }

        private Match GetLatestMatch(string summonerName, string accountId, List<Friend> friends)
        {
            ObjectConvertors convertors = new ObjectConvertors();
            Match generatedMatch = new Match();

            // Get data from response and put it in an object
            ElophantAPI.RecentGames.Data matches = JSONdownloader.RecentGames(accountId);
            List <ElophantAPI.RecentGames.FellowPlayer> matchFriendList = new List<ElophantAPI.RecentGames.FellowPlayer>();
            // Check if premade
            if (matches.gameStatistics[matches.gameStatistics.Count - 1].premadeSize > 0)
            {
                // ElophantAPI.RecentGames.GameStatistic match = new ElophantAPI.RecentGames.GameStatistic();

                // For each person in the game, check if in your team, yes? check if it is a friend and if so, add to list.
                for (int j = 0; j < matches.gameStatistics[matches.gameStatistics.Count - 1].fellowPlayers.Count; j++)
                {
                    if (matches.gameStatistics[matches.gameStatistics.Count - 1].fellowPlayers[j].teamId == matches.gameStatistics[matches.gameStatistics.Count - 1].teamId)
                    {
                        Friend derp =
                            friends.FirstOrDefault(
                                f => f.Name == matches.gameStatistics[matches.gameStatistics.Count - 1].fellowPlayers[j].summonerName);
                        if (derp != null)
                        {
                            matchFriendList.Add(matches.gameStatistics[matches.gameStatistics.Count - 1].fellowPlayers[j]);
                        }
                    }
                }

                // Done checking friends for 1 game, convert the statistics to match object to add to database
                generatedMatch = convertors.GameStatisticsToMatchObject(summonerName,
                                                                              matches.gameStatistics[matches.gameStatistics.Count - 1
                                                                                  ], matchFriendList, this);
                if (generatedMatch.Players.Count != 0)
                {
                    Player me = new Player
                    {
                        Name = summonerName,
                        Champion = matches.gameStatistics[matches.gameStatistics.Count - 1].championId,
                        Kills = convertors.Kills(matches.gameStatistics[matches.gameStatistics.Count - 1].statistics),
                        Deaths = convertors.Deaths(matches.gameStatistics[matches.gameStatistics.Count - 1].statistics),
                        Assists = convertors.Assists(matches.gameStatistics[matches.gameStatistics.Count - 1].statistics)
                    };
                    me.Score = (me.Kills + (me.Assists / 2) - me.Deaths);
                    generatedMatch.Players.Add(me);
                }
            }
            return generatedMatch;
        }
    }
}
